﻿using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Eneta.Portal.Common.Helpers
{
    /// <summary>
    /// Garbage collector for methods that make heavy use of regular expressions.
    /// </summary>
    public static class RegExHelper
    {
        //const string UrlPattern = @"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?";
        //const string UrlPattern = @"((http|ftp|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?";
        const string UrlPattern = @"(((http|ftp|https):\/\/)|(www\.))[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?";
        //private const string UrlPattern =
        //    @"([\d\w-.]+?\.(a[cdefgilmnoqrstuwz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvxyz]|d[ejkmnoz]|e[ceghrst]|f[ijkmnor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eouw]|s[abcdeghijklmnortuvyz]|t[cdfghjkmnoprtvwz]|u[augkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]|aero|arpa|biz|com|coop|edu|info|int|gov|mil|museum|name|net|org|pro)(\b|\W(?<!&|=)(?!\.\s|\.{3}).*?))(\s|$)";

        /// <summary>
        /// Detects web addresses in text and replace addresses with links.
        /// </summary>
        /// <param name="s">The string with text.</param>
        /// <returns>Returns string with input text where web addresses are made to links.</returns>
        public static string DetectAndReplaceUrls(string s)
        {
            if (string.IsNullOrEmpty(s))
                return s;

            var matches = Regex.Matches(s, UrlPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);

            var replacements = (from m in matches.Cast<Match>()
                                orderby m.Value.Length descending
                                select m.Value).ToList();
            
            var i = 0;
            var finalReplacements = new Dictionary<string, string>();
            
            foreach (var match in replacements.ToList())
            {
                finalReplacements.Add(i.ToString(), match);
                
                s = s.Replace(match, "{" + i + "}");
                i++;
            }

            foreach (var match in finalReplacements)
            {
                var link = @"<a href=""{0}"">{1}</a>";
                var url = match.Value;
                if (!url.StartsWith("http://") && !url.StartsWith("https://"))
                    url = "http://" + url;
                link = string.Format(link, url, match.Value);
                s = s.Replace("{"+match.Key+"}",link);
            }            
            return s;
        }

        /// <summary>
        /// Removes HTML tags from given string.
        /// </summary>
        /// <param name="s">The input string.</param>
        /// <returns>Returns string where HTML tags are removed.</returns>
        public static string RemoveHtmlTags(string s)
        {
            var result = Regex.Replace(s, "<[^>]*>", string.Empty);
            result = result.Replace("&quot;", "\"");

            return result;
        }

        public static string RemoveForbiddenAttributes(string html)
        {
            var forbiddenAttributes = new []{"id", "style"};
            var forbiddenTags = new[] {"font","span"};            
            
            Logger.LogInfo("RemoveForbiddenAttributes: input = " + html, "");

            foreach (var tag in forbiddenTags)
            {
                var regex = new Regex("<" + tag + "[^><]*>|<." + tag + "[^><]*>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                html = regex.Replace(html, string.Empty);
            }

            foreach (var attr in forbiddenAttributes)
            {
                var regex = new Regex("\\<(\\w+)\\s+(" + attr + "=\\\".*\")\\>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

                var matches = regex.Matches(html);
                //Logger.LogInfo("RemoveForbiddenAttributes: attr = " + attr, "");
                //Logger.LogInfo("RemoveForbiddenAttributes: regex = " + regex, "");
                //Logger.LogInfo("RemoveForbiddenAttributes: html = " + html, "");
                //Logger.LogInfo("RemoveForbiddenAttributes: matches = " + matches.Count, "");
                foreach (Match match in matches)
                {
                    /*Logger.LogInfo("RemoveForbiddenAttributes: match.Value = " + match.Value, "");
                    Logger.LogInfo("RemoveForbiddenAttributes: match.Groups[2].Value = " + match.Groups[2].Value, "");*/
                    html = html.Replace(match.Value, match.Value.Replace(match.Groups[2].Value, ""));
                }
            }
            html = html.Replace("<pre>", "<p>");
            html = html.Replace("<pre ", "<p ");
            html = html.Replace("</pre", "</p");

            html = html.Replace("<div>", "<p>");
            html = html.Replace("<div ", "<p ");
            html = html.Replace("</div", "</p");
            html = html.Replace("<p> </p>", "");

            html = html.Replace("<p>\r\n<p>", "<p>");
            html = html.Replace("</p>\r\n</p>", "</p>");

            Logger.LogInfo("RemoveForbiddenAttributes: final html = " + html, "");
            return html;
        }

        public static string CleanForumBody(string html)
        {
            var pattern = @"(\[quote\s+name=&quot;(?<user>\w+)&quot;\]|\[quote\])";
            var matches = Regex.Matches(html, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);

            foreach (Match match in matches)
            {
                foreach (var cap in match.Captures)
                    Logger.LogInfo("Capture: " + cap, "");

                var user = string.Empty;
                if (match.Groups["user"] != null)
                    user = match.Groups["user"].Value;
                var replace = string.Empty;

                if (!string.IsNullOrEmpty(user))
                {
                    replace += user + " kirjutas: ";
                }
                html = html.Replace(match.ToString(), replace);
            }
            html = html.Replace("[/quote]", "");
            //html = html.Replace("[/quote]", "");
           html = html.Replace("<p>&nbsp;</p>", "");
           html = html.Replace("<p></p>", "");
            html = html.Trim();
            return html;
        }
    }

}